package com.atguigu.tingshu.album.receiver;

import com.atguigu.tingshu.album.mapper.AlbumInfoMapper;
import com.atguigu.tingshu.album.mapper.TrackInfoMapper;
import com.atguigu.tingshu.album.service.AlbumInfoService;
import com.atguigu.tingshu.album.service.TrackInfoService;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.rabbit.constant.MqConst;
import com.atguigu.tingshu.vo.album.TrackStatMqVo;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**
 * @BelongsProject: tingshu-parent
 * @BelongsPackage: com.atguigu.tingshu.album.receiver
 * @Author: jiangyi
 * @CreateTime: 2025-10-13  19:03
 * @Description: TODO
 * @Version: 1.0
 */
@Component
public class TrackStatReciver {


    @Autowired
    private TrackInfoMapper trackStatMapper;
    @Autowired
    private AlbumInfoMapper albumStatMapper;

    @Autowired
    private RedisTemplate redisTemplate;


    /**
     * 监听更新专辑播放量,albumStat 、trackStat
     *
     * @param channel
     * @param message
     * @param mqVo
     */
    @RabbitListener(bindings = @QueueBinding(
            exchange = @Exchange(value = MqConst.EXCHANGE_TRACK),
            value = @Queue(value = MqConst.QUEUE_TRACK_STAT_UPDATE, durable = "true", autoDelete = "true"),
            key = {MqConst.ROUTING_TRACK_STAT_UPDATE}
    ))
    @Transactional(rollbackFor = Exception.class)
    public void updateTrackStat(Channel channel, Message message, TrackStatMqVo mqVo) {
        // 应考虑幂等性，一张专辑中的一个音频只记录一次且确保消息只消费一次，避免消息重复消费
        String businessNoKey = RedisConstant.BUSINESS_PREFIX + mqVo.getBusinessNo();
        // 模拟重试次数时长为 5min
        Boolean flag = redisTemplate.opsForValue().setIfAbsent(businessNoKey, mqVo.getBusinessNo(), 5, TimeUnit.MINUTES);
        try {
            if(flag){
                //2.更新声音统计信息 trackId 、 statType、 count
                trackStatMapper.updateStat(mqVo.getTrackId(), mqVo.getStatType(), mqVo.getCount());

                //3.更新专辑统计信息(播放量、评论量只要声音+1，对应专辑也得+1)
                if (SystemConstant.TRACK_STAT_PLAY.equals(mqVo.getStatType())) {
                    albumStatMapper.updateStat(mqVo.getAlbumId(), SystemConstant.ALBUM_STAT_PLAY, mqVo.getCount());
                }
                if (SystemConstant.TRACK_STAT_COMMENT.equals(mqVo.getStatType())) {
                    albumStatMapper.updateStat(mqVo.getAlbumId(), SystemConstant.ALBUM_STAT_COMMENT, mqVo.getCount());
                }
            }
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (Exception e) {
            try {
                // 更新失败时，类似事务回滚操作
                redisTemplate.delete(businessNoKey);
                channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
            } catch (IOException ex) {
                throw new RuntimeException(ex);
            }
            throw new RuntimeException(e);
        }


    }
}
